package utils.dataaccess;

import entities.Authorisation;
import entities.Forumblocks;
import entities.Forumposts;
import entities.Forumthreads;
import entities.Systemobserver;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * Database interface containing proxy for multiple datastorages access
 * @author Dezmond
 */
public class DBInterface {
    
    private static String loadDatasourceClassName() {
        try {
            return IOUtil.loadClassName();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(DBInterface.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(DBInterface.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
    /**
     * Reloads database interface type according to IoC ini-file (loacted in 
     * faces context directory). Used while
     * initialization of the DBInterface and in case of manual DB switch
     */
    public static void updateDatabaseUtil(){
        try {
            String className = loadDatasourceClassName();
            staticDelegate = (IDatabaseUtil) Class.forName("utils.dataaccess."+className).newInstance();
        } catch (Exception ex) {
            Logger.getLogger(DBInterface.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    /**
     * Persists defined classname to ini-file in faces-context directory
     * @param datasourceName 
     */
    public static void setDatasourceClassName(String datasourceName) {
        try {
            IOUtil.saveClassName(datasourceName);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(DBInterface.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(DBInterface.class.getName()).log(Level.SEVERE, null, ex);
        }
        updateDatabaseUtil();
    }
    
    
    /**
     * Proxy for data access.
     */
    private static IDatabaseUtil staticDelegate;
    
    /**
     * DatabaseUtil resolving block. Used instead of complicated IoC tools
     */
    static{
            if(staticDelegate == null){
                updateDatabaseUtil();
            }
    }
    
    public static ArrayList<Systemobserver> getStatistics(){
        return staticDelegate.getStatistics();
    }

     public static void changeGroup(Authorisation user, int groupID) {
        staticDelegate.changeGroup(user, groupID);
    }

    public static void delete(Object entity) {
        staticDelegate.delete(entity);
    }

    public static Forumblocks getBlockById(int blockID) {
        return staticDelegate.getBlockById(blockID);
    }

    public static Forumblocks getBlockByName(String value) {  
        return staticDelegate.getBlockByName(value);
    }

    public static ArrayList<Forumblocks> getBlocks() {
        return staticDelegate.getBlocks();
    }

    public static ArrayList<Forumthreads> getBlocksThreads(Forumblocks block) {
        return staticDelegate.getBlocksThreads(block);
    }

    public static Authorisation getByEmail(String email) { 
        return staticDelegate.getByEmail(email);
    }

    //ADMINISTRATIVE METHODS
    public static ArrayList<Authorisation> getEntries() {
        return staticDelegate.getEntries();
    }

    public static Authorisation getEntry(String username) {
        return staticDelegate.getEntry(username);
    }

    public static Authorisation getEntry(String username, String password) {
        return staticDelegate.getEntry(username, password);
    }

    public static ArrayList<Forumposts> getPosts(Forumthreads thread) {
        return staticDelegate.getPosts(thread);
    }

    public static ArrayList<Forumposts> getPosts(String pattern) {
       return staticDelegate.getPosts(pattern);
    }

    public static ArrayList<Forumposts> getPosts(Authorisation user) {
        return staticDelegate.getPosts(user);
    }

    public static Systemobserver getStatistics(Date date) {
        return staticDelegate.getStatistics(date);
    }

    public static Forumthreads getThreadById(int threadID) {
        return staticDelegate.getThreadById(threadID);
    }

    public static void increaseUserCounter() {
        staticDelegate.increaseUserCounter();
    }

    public static boolean isRegistered(String username) {
        return staticDelegate.isRegistered(username);
    }

    public static void moveThread(Forumthreads thread, Forumblocks sourceBlock, Forumblocks targetBlock) {
        staticDelegate.moveThread(thread, sourceBlock, targetBlock);
    }

    public static void persist(Object entity) {
        staticDelegate.persist(entity);
    }

    public static void save(Object entity) {
        staticDelegate.save(entity);
    }

    public static void updateEventCounter() {
        staticDelegate.updateEventCounter();
    }


}
